package code



//安装工具
import (
	"bufio"
	"fmt"
	"gitee.com/phpdi/ant-api/utils"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
)

const (
	ProjectDir = "./" //控制器目录

)

var (
	goFileRe=regexp.MustCompile(`.+\.go$`);
)

type Install struct {
	files []string //需要替换的文件
	fileTypes []string //需要替换的文件后缀

	oldPackageName string //旧的包名
	newPackageName string //新的包名
}

func NewInstall(newPackageName string) *Install {
	this:=&Install{
		oldPackageName:getOldPackageName(ProjectDir+"go.mod"),
		newPackageName: newPackageName,
	}

	this.listDir(ProjectDir)

	return this
}


//获取旧包名
func getOldPackageName(filePath string) (oldPackageName string) {

	if !utils.FileExist(filePath) {
		panic("Install.setOldPackageName 错误:go.mod文件缺失")
	}

	fi, err := os.Open(filePath)
	if err != nil {
		panic(err)
	}
	defer fi.Close()

	br := bufio.NewReader(fi)
	for {
		a, _, _ := br.ReadLine()
		oldPackageName=string(a)
		break
	}

	oldPackageName=strings.Replace(oldPackageName,"module","",1)
	oldPackageName=strings.Trim(oldPackageName," ")

	return
}




//获取指定目录下的所有文件和目录
func (this *Install) listDir(dirPth string)  {
	//fmt.Println(dirPth)
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		fmt.Println("Install.listDir 错误:",err)
		return
	}
	PthSep := string(os.PathSeparator)

	for _, fi := range dir {

		if fi.IsDir() {
			this.listDir(dirPth + PthSep + fi.Name())
		}else{
			if goFileRe.Match([]byte(fi.Name())) {
				this.files= append(this.files, dirPth+PthSep+fi.Name())
			}
		}
	}
	return
}

//开始安装
func (this *Install)Start()  {
	//项目下所有的go文件
	for _,file:=range this.files {
		replace(file,this.oldPackageName,this.newPackageName)
	}

	this.replaceGoMod(ProjectDir+"go.mod")
}

//处理gomod文件
func  (this *Install)replaceGoMod(file string)  {
	replace(file,this.oldPackageName,this.newPackageName)
}

//替换文件中的内容
func replace(path string,search string,replace string)  {
	content,err:=ioutil.ReadFile(path)
	if err != nil {
		return
	}

	str:=strings.Replace(string(content),search,replace,-1)

	if err:=ioutil.WriteFile(path,[]byte(str),0666);err!= nil {
		fmt.Println()
	}

}
